github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/appengine/blobstore_mgt/blobstore cmd line uploader.go (about) 1 package blobstore_mgt 2 3 // http://stackoverflow.com/questions/20144066/is-it-possible-to-store-arbitrary-data-in-gae-golang-blobstore 4 5 import ( 6 "bytes" 7 "net/http" 8 "mime/multipart" 9 10 "appengine" 11 "appengine/blobstore" 12 "appengine/urlfetch" 13 ) 14 15 const SampleData = `foo,bar,spam,eggs` 16 17 18 func blobAutoUploadTest(w http.ResponseWriter, r *http.Request) { 19 20 21 c := appengine.NewContext(r) 22 23 // First you need to create the upload URL: 24 upl_url, err := blobstore.UploadURL(c, "/blob/auto-upload", nil) 25 if err != nil { 26 http.Error(w, err.Error(), http.StatusInternalServerError) 27 c.Errorf("%s", err) 28 return 29 } 30 31 32 // Now you can prepare a form that you will submit to that URL. 33 var b1 bytes.Buffer 34 fw := multipart.NewWriter(&b1) 35 // Do not change the form field, it must be "file"! 36 // You are free to change the filename though, it will be stored 37 // in the BlobInfo. 38 file, err := fw.CreateFormFile("file", "filename-for-blobinfo-example.csv") 39 if err != nil { 40 http.Error(w, err.Error(), http.StatusInternalServerError) 41 c.Errorf("%s", err) 42 return 43 } 44 if _, err = file.Write([]byte(SampleData)); err != nil { 45 http.Error(w, err.Error(), http.StatusInternalServerError) 46 c.Errorf("%s", err) 47 return 48 } 49 // Don't forget to close the multipart writer. 50 // If you don't close it, your request will be missing the terminating boundary. 51 fw.Close() 52 53 54 55 56 // Now that you have a form, you can submit it to your handler. 57 req, err := http.NewRequest("POST", upl_url.String(), &b1) 58 if err != nil { 59 http.Error(w, err.Error(), http.StatusInternalServerError) 60 c.Errorf("%s", err) 61 return 62 } 63 64 // Don't forget to set the content type, this will contain the boundary. 65 req.Header.Set("Content-Type", fw.FormDataContentType()) 66 67 68 69 // Now submit the request. 70 client := urlfetch.Client(c) 71 res, err := client.Do(req) 72 if err != nil { 73 http.Error(w, err.Error(), http.StatusInternalServerError) 74 c.Errorf("%s", err) 75 return 76 } 77 c.Infof("Autouploader Status - %v", res.Status) 78 79 // Check the response status, it should be whatever you return in the `/upload` handler. 80 if res.StatusCode != http.StatusCreated && res.StatusCode != http.StatusOK{ 81 http.Error(w, err.Error(), http.StatusInternalServerError) 82 c.Errorf("bad status: %s", res.Status) 83 return 84 } 85 86 87 // Everything went fine. 88 w.WriteHeader(res.StatusCode) 89 } 90 91 92 func blobAutoUpload(w http.ResponseWriter, r *http.Request) { 93 94 c := appengine.NewContext(r) 95 96 // Here we just checked that the upload went through as expected. 97 if _, _, err := blobstore.ParseUpload(r); err != nil { 98 http.Error(w, err.Error(), http.StatusInternalServerError) 99 c.Errorf("%s", err) 100 return 101 } 102 // Everything seems fine. Signal the other handler using the status code. 103 w.WriteHeader(http.StatusCreated) 104 } 105 106 107 func init() { 108 http.HandleFunc("/blob/auto-upload-test", blobAutoUploadTest) 109 http.HandleFunc("/blob/auto-upload", blobAutoUpload) 110 }